package com.zzyl.service.impl;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.zzyl.constant.Constants;
import com.zzyl.dto.WechatLoginDto;
import com.zzyl.entity.Member;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.properties.JwtTokenManagerProperties;
import com.zzyl.properties.WechatConfigProperties;
import com.zzyl.service.CustomerLoginService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
public class CustomerLoginServiceImpl implements CustomerLoginService {
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private JwtTokenManagerProperties jwtTokenManagerProperties;

    @Autowired
    private WechatConfigProperties wechatConfigProperties;

//    @Value("${zzyl.framework.wx.appid}")
//    private String appid;
//
//    @Value("${zzyl.framework.wx.secret}")
//    private String secret;
    /**
     * 微信登录
     * @param wechatLoginDto
     * @return
     */
    @Override
    public LoginVo login(WechatLoginDto wechatLoginDto) {
        //1.通过登录凭证code完成登录 获取唯一的openId
        String OpenId = getOpenId(wechatLoginDto.getCode());
        //2.通过openid查询数据库的表
        Member member = memberMapper.selectByOpenId(OpenId);
        //3.通过手机兑换码获取手机号
        String phone = getPhone(wechatLoginDto.getPhoneCode());
        //4.判断用户是否为新用户 如果是则注册 不是则更新用户的手机号
        if(member == null){
            //新用户--->新增
            member = new Member();
            member.setOpenId(OpenId);
            member.setPhone(phone);
            member.setCreateTime(LocalDateTime.now());
            member.setUpdateTime(LocalDateTime.now());
            member.setCreateBy(1L);
            String nickName = Constants.DEFAULT_NICKNAME_PREFIX.get((int)(Constants.DEFAULT_NICKNAME_PREFIX.size()*Math.random()))+phone.substring(phone.length()-4);
            member.setName(nickName);

            memberMapper.save(member);
        }else {
            if(member.getPhone().equals(phone)){
                member.setUpdateTime(LocalDateTime.now());
                member.setUpdateBy(1L);
                member.setPhone(phone);

                memberMapper.update(member);
            }
        }
        //5.生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.JWT_USERID, member.getId());
        claims.put(Constants.JWT_USERNAME, member.getName());

        String token = JwtUtil.createJWT(jwtTokenManagerProperties.getBase64EncodedSecretKey(), jwtTokenManagerProperties.getTtl(), claims);

        //6.构建返回结果
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setNickName(member.getName());
        return loginVo;
    }

    /**
     * 发送请求获取OpenId
     * @param code
     * @return
     */
    private String getOpenId(String code) {
        Map<String, Object> paramData = new HashMap<>();
        paramData.put("appid", wechatConfigProperties.getAppId());
        paramData.put("secret", wechatConfigProperties.getSecret());
        paramData.put("js_code",code);
        paramData.put("grant_type", "authorization_code");

        HttpResponse response = HttpUtil.createGet(Constants.OPENID_REQUEST_URL).form(paramData).execute();

        String jsonResult = response.body();
        JSONObject jsonObject = JSONUtil.parseObj(jsonResult);

        if( jsonObject.getInt("errcode") != null){
            throw new BaseException(BasicEnum.GET_OPENID_ERROR);
        }
        return jsonObject.getStr("openid");
    }

    /**
     * 发送Get请求获取AccessToken
     * @return
     */
    private String getAccessToken() {
        Map<String, Object> paramData = new HashMap<>();
        paramData.put("grant_type", "client_credential");
        paramData.put("appid", wechatConfigProperties.getAppId());
        paramData.put("secret", wechatConfigProperties.getSecret());

        HttpResponse response = HttpUtil.createGet(Constants.WX_ACCESS_TOKEN_URL).form(paramData).execute();

        String jsonResponse = response.body();
        JSONObject jsonObject = JSONUtil.parseObj(jsonResponse);

        if(jsonObject.getStr("access_token") == null) {
            throw new BaseException(BasicEnum.GET_TOKEN_ERROR);
        }

        return jsonObject.getStr("access_token");
    }

    /**
     * 根据code和AccessToken获取手机号
     * @param phoneCode
     * @return
     */
    public String getPhone(String phoneCode) {
        //1.获取AccessToken
        String accessToken = getAccessToken();

        //2.通过AccessToken和code码获取手机号
        Map<String, Object> paramData = new HashMap<>();
        paramData.put("code", phoneCode);

        HttpResponse response = HttpUtil.createPost(Constants.WX_GET_PHONE_URL+accessToken).body(JSONUtil.toJsonStr(paramData)).execute();

        String jsonResponse = response.body();

        JSONObject jsonObject = JSONUtil.parseObj(jsonResponse);
        if(jsonObject.getInt("errcode") != null && jsonObject.getInt("errcode") != 0 ){
            throw new BaseException(BasicEnum.GET_PHONE_ERROR);
        }
        JSONObject phoneInfo = jsonObject.getJSONObject("phone_info");

        return phoneInfo.getStr("phoneNumber");
    }


}
